package io.ouka.pub.util;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;

/**
 * 日期处理工具类
 */
public class DateUtils {

    public static final String DATE_FORMAT = "yyyy-MM-dd";
    public static final String DATE_TIME_FORMAT = "yyyy-MM-dd HH:mm:ss";

    /**
     * 格式化日期成字符串
     *
     * @param date
     * @return 返回yyyy-MM-dd格式字符串
     */
    public static String format(Date date) {
        return format(date, DATE_FORMAT);
    }

    /**
     * 格式化日期成字符串
     *
     * @param date
     * @return 返回yyyy-MM-dd HH:mm:ss格式字符串
     */
    public static String formatDateTime(Date date) {
        return format(date, DATE_TIME_FORMAT);
    }

    /**
     * 按指定格式格式化日期
     *
     * @param date
     * @param format
     * @return
     */
    public static String format(Date date, String format) {
        if (date == null)
            return null;

        SimpleDateFormat dateFormat = new SimpleDateFormat(format);
        return dateFormat.format(date);
    }

    /**
     * 按指定格式将字符串转化日期
     *
     * @param date
     * @param format
     * @return
     */
    public static Date parse(String date, String format) {
        if (date == null || date.trim().isEmpty())
            return null;
        SimpleDateFormat dateFormat = new SimpleDateFormat(format);

        try {
            return dateFormat.parse(date);
        } catch (ParseException e) {
            throw new RuntimeException("格式化错误", e);
        }
    }

    /**
     * 按格式yyyy-MM-dd，将字符串转化日期
     *
     * @param date
     * @return
     */
    public static Date parse(String date) {
        return parse(date, DATE_FORMAT);
    }

    /**
     * 获取日期中的年，比如2016
     *
     * @param date 日期
     * @return 年份
     */
    public static int getYear(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        return calendar.get(Calendar.YEAR);
    }

    /**
     * 获取日期中的月份，1-12
     *
     * @param date
     * @return
     */
    public static int getMonth(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        return calendar.get(Calendar.MONTH) + 1;
    }

    /**
     * 获取日期中的月份的某号，1-(28,29,30,31)
     *
     * @param date
     * @return
     */
    public static int getDay(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        return calendar.get(Calendar.DATE);
    }

    /**
     * 获取午夜时间 12点整
     *
     * @param date
     * @return
     */
    public static Date getMidnight(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.set(Calendar.HOUR, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        calendar.set(Calendar.MILLISECOND, 0);

        return calendar.getTime();
    }

    /**
     * 获取月份的第一天
     *
     * @param date
     * @return
     */
    public static Date getFirstDayOfMonth(Date date) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        cal.set(Calendar.DAY_OF_MONTH, cal.getMinimum(Calendar.DATE));

        return getMidnight(cal.getTime());
    }

    /**
     * 获取月份的最后一天
     *
     * @param date
     * @return
     */
    public static Date getLastDayOfMonth(Date date) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        cal.set(Calendar.DAY_OF_MONTH, cal.getActualMaximum(Calendar.DATE));

        return getMidnight(cal.getTime());
    }

    /**
     * 判断年份是否为闰年
     *
     * @param year 指定年
     * @return boolean 是否是闰年的标识
     */
    public static boolean isLeapYear(int year) {
        boolean leadyear;
        if (year % 4 == 0 && year % 100 != 0) {
            leadyear = true;
        } else if (year % 400 == 0) {
            leadyear = true;
        } else {
            leadyear = false;
        }
        return leadyear;
    }

    /**
     * 比较两个日期的大小
     *
     * @param d1 指定日期1
     * @param d2 指定日期2
     * @return int 返回结果 1:d1>d2 0:d1=d2 -1:d1<d2
     */
    public static int compareDate(Date d1, Date d2) {
        Calendar c1 = Calendar.getInstance();
        Calendar c2 = Calendar.getInstance();
        c1.setTime(d1);
        c2.setTime(d2);
        int result = c1.compareTo(c2);
        return result;
    }

    /**
     * 增加日期的年份
     *
     * @param date  日期
     * @param years 增加数量。可为负数
     * @return 增加年份后的日期
     */
    public static Date addYear(Date date, int years) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.YEAR, years);
        return calendar.getTime();
    }

    /**
     * 增加日期的月份
     *
     * @param date   日期
     * @param months 增加数量。可为负数
     * @return 增加月份后的日期
     */
    public static Date addMonth(Date date, int months) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.MONTH, months);
        return calendar.getTime();
    }

    /**
     * 增加日期的天数
     *
     * @param date 日期
     * @param days 增加数量。可为负数
     * @return 增加天数后的日期
     */
    public static Date addDay(Date date, int days) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.DATE, days);
        return calendar.getTime();
    }

    /**
     * 增加日期的小时
     *
     * @param date  日期
     * @param hours 增加数量。可为负数,24小时制
     * @return 增加小时后的日期
     */
    public static Date addHour(Date date, int hours) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.HOUR_OF_DAY, hours);
        return calendar.getTime();
    }

    /**
     * 增加日期的分钟
     *
     * @param date    日期
     * @param minutes 增加数量。可为负数
     * @return 增加分钟后的日期
     */
    public static Date addMinute(Date date, int minutes) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.MINUTE, minutes);
        return calendar.getTime();
    }

    /**
     * 增加日期的秒钟
     *
     * @param date    日期
     * @param seconds 增加数量。可为负数
     * @return 增加秒钟后的日期
     */
    public static Date addSecond(Date date, int seconds) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.SECOND, seconds);
        return calendar.getTime();
    }

    /**
     * 计算自然年差，如自然年龄，周岁计算等
     *
     * @param date1
     * @param date2
     * @return
     */
    public static double getNaturalDiffYears(Date date1, Date date2) {
        Calendar calendarNow = Calendar.getInstance();
        calendarNow.setTime(date1);
        Calendar calendarCmp = Calendar.getInstance();
        calendarCmp.setTime(date2);

        double yearDiff = calendarNow.get(Calendar.YEAR) - calendarCmp.get(Calendar.YEAR);
        double monthDiff = calendarNow.get(Calendar.MONTH) - calendarCmp.get(Calendar.MONTH);
        double DaysDiff = calendarNow.get(Calendar.DATE) - calendarCmp.get(Calendar.DATE);
        boolean isLeapYear = isLeapYear(calendarNow.get(Calendar.YEAR));

        return yearDiff + monthDiff / 12 + (DaysDiff / (isLeapYear ? 366 : 365));
    }

    /**
     * 两个日期的年份之差
     *
     * @param date1
     * @param date2
     * @return 相差年数
     */
    public static int getDiffYears(Date date1, Date date2) {
        Calendar calendarNow = Calendar.getInstance();
        calendarNow.setTime(date1);
        Calendar calendarCmp = Calendar.getInstance();
        calendarCmp.setTime(date2);

        return calendarNow.get(Calendar.YEAR) - calendarCmp.get(Calendar.YEAR);
    }

}
